package grafica;
import game.GameCore;
import game.Livello;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.*;

import sprite.Giocatore;
import sprite.Mattone;
import sprite.Nemico;
import sprite.Proiettile;
import sprite.Sprite;

public class GamePanel extends JPanel implements Runnable,KeyListener {
	//GameCore game;
	Livello level;
	Toolkit t;
	Image im;
	MediaTracker mt;
	int playerID;
	ArrayList<Nemico> nemici;
	Myframe mf;
	boolean fine = false;
	Image background;

	private boolean stampaLoad;
	private boolean stampaSalva;
	
	Giocatore megaman;
	
	public GamePanel(Livello level,Myframe mf) {
		super();
		this.mf = mf;
		mt = new MediaTracker(this);
		t= Toolkit.getDefaultToolkit();
		//game = new GameCore(livello);
		this.level = level;
		playerID = 0;
		background = level.getImgBackground();
		
		this.addKeyListener(this);
		this.setFocusable(true);
		
		megaman = level.getPlayerAt(playerID);
		nemici = level.getNemici();
		//nemico = game.getLevel().getNemicoAt(0);
		//nemico.setGiocatore(megaman);
		for(Nemico n:nemici) {
			n.setGiocatore(megaman);
		}
		
		int k = 0;
		//carico nel media tracker tutti i tile
		for(int i=0;i < level.getHeight();i++) {
			for (int j = 0; j < level.getWidth(); j++) {
				if (level.getMappaElement(i, j) != null) {
					mt.addImage(level.getMappaElement(i, j).getImgElement(0), k);
					k++;
				}
			}
		}

		//carico nel media tracker tutte le immagini del player
		int i = 0;
		for(; i < megaman.getImg().size();i++) {
			mt.addImage(megaman.getImgElement(i), k+1+i);
		}


		
		//carico nel media tracker tutte le immagini del nemico
		int kj = 1;
		for(Nemico n:nemici) {		
			for(int j = 0; j < n.getImg().size();j++) {
				mt.addImage(n.getImgElement(j),k+i+1+kj);
				kj++;
			
			}
		}
		mt.addImage(background,k+i+1+kj+1);
		
					
		try {
			mt.waitForAll();
		} catch (InterruptedException e) {

			e.printStackTrace();
		}
		//se il livello ha un suono
		if(!level.getSottofondo().getSuono().isEmpty())
			level.getSottofondo().playLoop(1);
		//creo e avvio il thread del pannello
		new Thread(this).start();	
		//avvio i thread del player e dei nemici
		megaman.setAttivaThread(true);
		for(Nemico n:nemici) {	
			n.setAttivaThread(true);
		}

	}
	
	public void paintComponent(Graphics g) {
		g.setColor(level.getBackground());
	    g.fillRect(0, 0, Myframe.SCREEN_WIDTH,Myframe.SCREEN_HEIGHT);
	    if(background != null) {
	    	int iniziale = (400 *
	    	    (Myframe.SCREEN_WIDTH - background.getWidth(null)) /
	    	    (Myframe.SCREEN_WIDTH - level.getWidth() * Livello.TILE_SIZE));
	    	int backgroundX = iniziale+(megaman.getOffSetX() *
	    			(Myframe.SCREEN_WIDTH - background.getWidth(null)) /
	    			(Myframe.SCREEN_WIDTH - level.getWidth() * Livello.TILE_SIZE))*-1; 
	    	g.drawImage(background,backgroundX,0,null);
	    }
		int firstTile = level.getFirstTile(0);
		int lastTile = level.getLastTile(0);
		int modulo;
		
		if (megaman.getX() < (Myframe.SCREEN_WIDTH/2))
			modulo = 0;
		else
			modulo = level.getModulo(0);
		
		g.setColor(new Color(180,0,0));
		
		g.drawString("VITE ", 60, 25);
		for(int v=0;v< megaman.getVite();v++) {
			g.drawImage(t.getImage("images/testa.gif"), v*25 + 100, 10, null);
		}
		
		g.drawString("Energia ", 200, 25);
		g.fillRect(250, 15, megaman.getEnergia()/2, 10);	
		g.drawString("Punteggio: " + megaman.getPunteggio(), 450, 22);
		for(int i = 0; i < level.getHeight();i++) {
			for (int j = firstTile,k=0; j <= lastTile; j++,k++) {
				if (level.getMappaElement(i, j) != null) {
				
				g.drawImage(level.getMappaElement(i, j).getImgElement(0),k*Livello.TILE_SIZE - modulo,i*Livello.TILE_SIZE,null);
				}
			}
		}
		g.drawImage(megaman.getImgElement(megaman.getCurrentFrame()), megaman.getX(),megaman.getY(), null);
		
		for(Nemico nemico:nemici) {
			if(isNemicoOnScreen(nemico)) {
				g.drawImage(nemico.getImgElement(nemico.getCurrentFrame()), nemico.getX(),nemico.getY(), null);					
			}
			
			synchronized(nemico.getProiettili()) {
				Iterator<Proiettile> it = nemico.getProiettili().iterator();
				while(it.hasNext()) {
					Proiettile proiettile2 = it.next();								
						g.drawImage(proiettile2.getImgElement(0), proiettile2.getX() - 10, proiettile2.getY(), null);			
				}
			}
		}
		
		synchronized (this) {
			if( stampaSalva ){
				g.drawString("Salvato", 320, 50);
			}
			if ( stampaLoad ){
				g.drawString("Caricato", 320, 50);
			}
		}
			
		//for(Proiettile proiettile: megaman.getProiettili()) {
			synchronized(megaman.getProiettili()) {
				Iterator<Proiettile> it = megaman.getProiettili().iterator();
		
				while(it.hasNext()) {
					Proiettile proiettile = it.next();	
					g.drawImage(proiettile.getImgElement(0), proiettile.getX() - 10, proiettile.getY(), null);			
				}
			}
	}
	
	public boolean isNemicoOnScreen(Nemico n) {
		
		if(n.getOffSetX() >  megaman.getOffSetX() - Myframe.SCREEN_WIDTH/2 && n.getOffSetX() <  megaman.getOffSetX() + Myframe.SCREEN_WIDTH/2) {						
			if (!n.isVisible()) {
				//stabilisce la posizione iniziale del nemico quando appare sullo schermo
				n.setX(n.getOffSetX() - (megaman.getOffSetX() - 400));
				n.setVisible(true);
			}
			return true;
		} else {
			n.setVisible(false);
			n.setCorri(false);
			return false;
		}
		
	}
	
	public void controllaCollisioni() {
		Iterator<Proiettile> it;
		for(Nemico n:nemici) {
			if(n.collidesWidth(megaman) && n.isVivo()) {
				megaman.setEnergia(megaman.getEnergia() - 1);
				System.out.println("Giocatore Colpito");
			}

			synchronized(megaman.getProiettili()) {
				it = megaman.getProiettili().iterator();				
				while(it.hasNext()) {
					Proiettile p = it.next();
					if(n.isVivo() && p.collidesWidth(n)) {
						n.setVivo(false);
						System.out.println("Nemico colpito");
						it.remove();
						megaman.setPunteggio(megaman.getPunteggio() + 10);
					}
				}
			}			
			
			synchronized(n.getProiettili()) {
				it = n.getProiettili().iterator();				
				while(it.hasNext()) {
					Proiettile p = it.next();
					if(p.collidesWidth(megaman)) {
						System.out.println("Giocatore Proiettile");
						megaman.setEnergia(megaman.getEnergia() - 50);
						it.remove();
					}
				}
			}
		}
			
		
	}
	
	public void run() {
		
		while(!fine) {

			controllaCollisioni();
			this.repaint();
			
			if(megaman.getEnergia() < 1) {
				megaman.setVivo(false);		
				if(megaman.isFineAnimazione()) {
					this.fine = true;
					///megaman.setFine(true);
					for(Nemico n:nemici) {
						n.setFine(true);
					}
					//controllo sulle vite se sono < 0 chiama un pannello di gameover
					level.getSottofondo().stop(1);
					if(megaman.getVite() < 0)
						mf.gameOver();
					else
						mf.changePanel(megaman,level.getIdLivello(),false,level.isType());				
				}
			}
			
			if(megaman.isLivelloSuperato()) {
				level.getSottofondo().stop(1);
				changeLevel();
			}
				
			
			try {
				Thread.sleep(23);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	public void changeLevel() {
		this.fine = true;
		//megaman.setFine(true);
		for(Nemico n:nemici) {
			n.setFine(true);
		}
		megaman.setOffSetX(400);
		megaman.setX(55);
		megaman.setY(10);
		
		int l = level.getIdLivello();
		//mf.changePanel(megaman,l,true,level.isType());
		/*
		 * 
		 * SE IL LIVELLO E' L'ULTIMO NON CHIAMARE NEXTPANEL MA CHIAMA ENDPANEL
		 */
		if(l == 5)
			mf.vittoria();
		else {
			if(level.isType())
				mf.nextPanel(megaman, l,level.isType());
			else
				mf.menu();
		}
		
		megaman.setMappa(level.getMappa());		
	}

	public void keyPressed(KeyEvent e) {
		if(megaman.isVivo()) {
			if (e.getKeyCode() == e.VK_RIGHT) {
				megaman.possoAndareAvanti();		
			}
			else if (e.getKeyCode() == e.VK_LEFT) {
				megaman.possoAndareIndietro();
			}
			else if (e.getKeyCode() == e.VK_UP) {		 
				megaman.possoSaltare();
			}	
			else if (e.getKeyCode() == e.VK_DOWN) {
				megaman.lowered(); 
			}
			else if (e.getKeyCode() == e.VK_SPACE) {
				megaman.shoot();
			}
			else if (e.getKeyCode() == e.VK_D) {			

			}
			else if (e.getKeyCode() == e.VK_P) { //PAUSA
				if(megaman.isAttivaThread()) {
					megaman.setAttivaThread(false);
					for(Nemico n:nemici) {
						n.setAttivaThread(false);
					}
				} else {
					megaman.setAttivaThread(true);
					for(Nemico n:nemici) {
						n.setAttivaThread(true);
					}					
				}
			}
		}

		
	}


	public void keyReleased(KeyEvent e) {
		if(megaman.isVivo()) {
			if (e.getKeyCode() == e.VK_RIGHT) {
				megaman.setCorri(false);		
			}
			else if (e.getKeyCode() == e.VK_LEFT) {
				megaman.setCorri(false);
			}
			else if (e.getKeyCode() == e.VK_SPACE) {
				megaman.setSpara(false);
			}
		}

	}


	public void keyTyped(KeyEvent e) {
		
	}

	public Giocatore getMegaman() {
		return megaman;
	}

	public void setMegaman(Giocatore megaman) {
		this.megaman = megaman;
	}

	public int getPlayerID() {
		return playerID;
	}

	public void setPlayerID(int playerID) {
		this.playerID = playerID;
	}
	
	public boolean isStampaLoad() {
		return stampaLoad;
	}

	public void setStampaLoad(boolean stampaLoad) {
		this.stampaLoad = stampaLoad;
	}

	public boolean isStampaSalva() {
		return stampaSalva;
	}

	public void setStampaSalva(boolean stampaSalva) {
		this.stampaSalva = stampaSalva;
	}
}